home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / WIN_VID / WINBM20.ZIP;1 / BMMANIP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-19  |  18.8 KB  |  840 lines

  1. /*
  2. **    $id: ssvcid bmmanip.c 1.3 08/03/92 10:00 am$
  3. **        This file contains various functions for manipulating bitmaps.
  4. **
  5. **    (C) 1991-3    Larry Widing
  6. */
  7. #include    <windows.h>
  8. #include    <dos.h>
  9. #include    <malloc.h>
  10. #include    "bitmaps.h"
  11. #include    "bmmanip.h"
  12.  
  13. /*
  14. ** int                                                number of color entries in header
  15. ** DIBitmapColors(BITMAPINFO FAR *bmi);    pointer to bitmap header
  16. **
  17. **    This function returns the number of colors in the color table of
  18. **    the specified Device-Independant Bitmap.
  19. **
  20. ** Modification History:
  21. ** 09/12/91  LCW  Created
  22. */
  23. int
  24. DIBitmapColors(BITMAPINFO FAR *bmi)
  25. {
  26.     if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
  27.     {
  28.         /*
  29.         **    OS/2 PM Bitmap, use bcBitCount field to determine colors
  30.         */
  31.         switch (((BITMAPCOREINFO FAR *)bmi)->bmciHeader.bcBitCount)
  32.         {
  33.             case 1:
  34.                 return 2;    /* Monochrome bitmap -> 2 colors */
  35.  
  36.             case 4:
  37.                 return 16;    /* 4-bit image -> 16 colors */
  38.  
  39.             case 8:
  40.                 return 256;    /* 8-bit image -> 256 colors */
  41.  
  42.             case 24:
  43.                 return 0;    /* 24-bt image -> 0 colors in color table */
  44.         }
  45.     }
  46.     else
  47.     {
  48.         /*
  49.         **    Windows bitmap
  50.         */
  51.         if (bmi->bmiHeader.biClrUsed == 0)
  52.         {
  53.             /* Maximum number of entries */
  54.             switch (bmi->bmiHeader.biBitCount)
  55.             {
  56.                 case 1:
  57.                     return 2;    /* Monochrome bitmap -> 2 colors */
  58.  
  59.                 case 4:
  60.                     return 16;    /* 4-bit image -> 16 colors */
  61.  
  62.                 case 8:
  63.                     return 256;    /* 8-bit image -> 256 colors */
  64.  
  65.                 case 24:
  66.                     return 0;    /* 24-bt image -> 0 colors in color table */
  67.             }
  68.         }
  69.         else
  70.         {
  71.             return (int)bmi->bmiHeader.biClrUsed;
  72.         }
  73.     }
  74.  
  75.     return 0;
  76. }
  77.  
  78. /*
  79. ** LPSTR                                            pointer to bitmap bits
  80. ** DIBitmapBits(BITMAPINFO FAR *bmi);    pointer to bitmap header
  81. **
  82. **    This function returns a pointer to the bits in a packed Device-
  83. **    Independant Bitmap.
  84. **
  85. ** Modification History:
  86. ** 09/12/91  LCW  Created
  87. */
  88. LPSTR
  89. DIBitmapBits(BITMAPINFO FAR *bmi)
  90. {
  91.     LPSTR    bits;
  92.     int    colors = DIBitmapColors(bmi);
  93.  
  94.     bits = ((LPSTR)bmi) + (unsigned int)bmi->bmiHeader.biSize;
  95.  
  96.     if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
  97.     {
  98.         bits += colors * sizeof(RGBTRIPLE);
  99.     }
  100.     else
  101.     {
  102.         bits += colors * sizeof(RGBQUAD);
  103.     }
  104.  
  105.     return bits;
  106. }
  107.  
  108. /*
  109. ** HPALETTE                                Handle to created palette, NULL if an error occurred
  110. ** CreateDibPalette(HDIB hbm);    Haldle to DIB needing a palette
  111. **
  112. ** Programmer       : LCW
  113. ** Functions Called : DIBitmapColors(), DibIsOs2()
  114. ** Globals Changed  : none
  115. **
  116. **    This function creates a logical palette for the specified DIB.
  117. **
  118. ** Modification History:
  119. ** 12/18/91  LCW  Created
  120. */
  121. HPALETTE
  122. CreateDibPalette(HDIB hbm)
  123. {
  124.     int                    i;                /* loop counter */
  125.     int                    numColors;    /* number of colors in color table */
  126.     LPLOGPALETTE        pal;            /* Pointer to logical palette */
  127.     HANDLE                handle;        /* Handle to logical palette memory block */
  128.     HPALETTE                palette;        /* Handle of logical palette */
  129.     LPBITMAPINFO        bmi;            /* Pointer to bitmap info structure */
  130.     LPBITMAPCOREINFO    bmci;            /* Pointer to OS/2 bitmap info structure */
  131.  
  132.     /*
  133.     **    Setup defaults
  134.     */
  135.     palette = (HPALETTE)NULL;
  136.  
  137.     if (hbm != (HDIB)NULL)
  138.     {
  139.         /* Get a pointer to the DIB's memory block */
  140.         bmi = (LPBITMAPINFO)GlobalLock(hbm);
  141.  
  142.         if (bmi != NULL)
  143.         {
  144.             /* Get the number of colors in this DIB */
  145.             numColors = DIBitmapColors(bmi);
  146.  
  147.             if (numColors > 0)
  148.             {
  149.                 /* Allocate memory for LOGPALETTE structure */
  150.                 handle = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
  151.                     sizeof(LOGPALETTE) + numColors * sizeof(PALETTEENTRY));
  152.  
  153.                 if (handle != (HANDLE)NULL)
  154.                 {
  155.                     /* Lock LOGPALETTE structure into memory */
  156.                     pal = (LPLOGPALETTE)GlobalLock(handle);
  157.                     if (pal != NULL)
  158.                     {
  159.                         /* Set version number and color count */
  160.                         pal->palVersion = 0x0300;
  161.                         pal->palNumEntries = numColors;
  162.  
  163.                         /*
  164.                         **    Set color values into paletee entries
  165.                         */
  166.                         if (DibIsOs2(hbm))
  167.                         {
  168.                             /* Copy RGBTRIPLEs into palette entries */
  169.                             bmci = (LPBITMAPCOREINFO)bmi;
  170.                             for (i = 0 ; i < numColors ; ++i)
  171.                             {
  172.                                 pal->palPalEntry[i].peRed = bmci->bmciColors[i].rgbtRed;
  173.                                 pal->palPalEntry[i].peGreen = bmci->bmciColors[i].rgbtGreen;
  174.                                 pal->palPalEntry[i].peBlue = bmci->bmciColors[i].rgbtBlue;
  175.                                 pal->palPalEntry[i].peFlags = 0;
  176.                             }
  177.                         }
  178.                         else
  179.                         {
  180.                             /* Copy RGBQUADs into palette entries */
  181.                             for (i = 0 ; i < numColors ; ++i)
  182.                             {
  183.                                 pal->palPalEntry[i].peRed = bmi->bmiColors[i].rgbRed;
  184.                                 pal->palPalEntry[i].peGreen = bmi->bmiColors[i].rgbGreen;
  185.                                 pal->palPalEntry[i].peBlue = bmi->bmiColors[i].rgbBlue;
  186.                                 pal->palPalEntry[i].peFlags = 0;
  187.                             }
  188.                         }
  189.  
  190.                         /* Create the logical palette */
  191.                         palette = CreatePalette(pal);
  192.  
  193.                         GlobalUnlock(handle);
  194.                     }
  195.                     GlobalFree(handle);
  196.                 }
  197.             }
  198.             GlobalUnlock(hbm);
  199.         }
  200.     }
  201.  
  202.     return palette;
  203. }
  204.  
  205. /*
  206. ** BOOL                    TRUE if successful, FALSE otherwise
  207. ** DrawBitmap(
  208. **   HDC hdc,            Handle of target device context
  209. **   int x,                X coordinate to draw bitmap at
  210. **   int y,                Y coordinate to draw bitmap at
  211. **   HBITMAP hbm);    Handle of bitmap to draw
  212. **
  213. **    This function draws the specified bitmap onto the target device
  214. **    context at the given coordinates.  If an error occurs, the FALSE will
  215. **    be returned to the caller, otherwise TRUE will be returned if the
  216. **    bitmap was drawn without a problem.
  217. **
  218. ** Modification History:
  219. ** 09/09/91  LCW  Created
  220. */
  221. BOOL
  222. DrawBitmap(HDC hdc, int x, int y, HBITMAP hbm)
  223. {
  224.     HDC        hdcMem;            /* Handle of memory context to use in drawing bitmap */
  225.     HBITMAP    oldBm;
  226.     POINT        ptSize, ptOrg;
  227.     BITMAP    bm;
  228.  
  229.     hdcMem = CreateCompatibleDC(hdc);
  230.     if (hdcMem != (HDC)NULL)
  231.     {
  232.         /*
  233.         **    Select bitmap to be draw into memory context
  234.         */
  235.         oldBm = SelectObject(hdcMem, hbm);
  236.  
  237.         /*
  238.         **    Set the mapping mode for the memory context to match the
  239.         **    target device context.
  240.         */
  241.         SetMapMode(hdcMem, GetMapMode(hdc));
  242.  
  243.         /*
  244.         **    Get the details of the bitmap being drawn
  245.         */
  246.         GetObject(hbm, sizeof(BITMAP), (LPSTR)&bm);
  247.  
  248.         /*
  249.         **    Adjust height and width for mapping mode
  250.         */
  251.         ptSize.x = bm.bmWidth;
  252.         ptSize.y = bm.bmHeight;
  253.         DPtoLP(hdc, (LPPOINT)&ptSize, 1);
  254.  
  255.         /*
  256.         **    Adjust origin for mapping mode
  257.         */
  258.         ptOrg.x = 0;
  259.         ptOrg.y = 0;
  260.         DPtoLP(hdcMem, (LPPOINT)&ptOrg, 1);
  261.  
  262.         /*
  263.         **    Draw the bitmap
  264.         */
  265.         BitBlt(hdc, x, y, ptSize.x, ptSize.y, hdcMem, ptOrg.x, ptOrg.y, SRCCOPY);
  266.  
  267.         /*
  268.         **    Clean up
  269.         */
  270.         SelectObject(hdcMem, oldBm);
  271.         DeleteDC(hdcMem);
  272.  
  273.         return TRUE;
  274.     }
  275.     return FALSE;
  276. }
  277.  
  278. /*
  279. ** BOOL                    TRUE if successful, FALSE if an error occurred
  280. ** DrawDIBitmap(
  281. **   HDC hdc,            Handle of target device context
  282. **   int x,                X coordinate to draw bitmap at
  283. **   int y,                Y coordinate to draw bitmap at
  284. **   HDIB hbm);        Handle of memory block holding packed DIB
  285. **
  286. **    This function draws the specified DI bitmap onto the target device
  287. **    context at the given coordinates.  If an error occurs, the FALSE will
  288. **    be returned to the caller, otherwise TRUE will be returned if the DI
  289. **    bitmap was drawn without a problem.
  290. **
  291. ** Modification History:
  292. ** 09/09/91  LCW  Created
  293. */
  294. BOOL
  295. DrawDIBitmap(HDC hdc, int x, int y, HDIB hbm, HPALETTE palette)
  296. {
  297.     int                width, height;
  298.     BITMAPINFO FAR    *bmi;
  299.     LPSTR                bits;
  300.     HPALETTE            oldPal = (HPALETTE)NULL;
  301.  
  302.     bmi = (BITMAPINFO FAR *)GlobalLock(hbm);
  303.     if (bmi != NULL)
  304.     {
  305.         bits = DIBitmapBits(bmi);
  306.  
  307.         if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
  308.         {
  309.             width = ((BITMAPCOREINFO FAR *)bmi)->bmciHeader.bcWidth;
  310.             height = ((BITMAPCOREINFO FAR *)bmi)->bmciHeader.bcHeight;
  311.         }
  312.         else
  313.         {
  314.             width = (WORD)bmi->bmiHeader.biWidth;
  315.             height = (WORD)bmi->bmiHeader.biHeight;
  316.         }
  317.  
  318.         if (palette != (HPALETTE)NULL)
  319.         {
  320.             oldPal = SelectPalette(hdc, palette, FALSE);
  321.             RealizePalette(hdc);
  322.         }
  323.  
  324.         SetDIBitsToDevice(hdc, x, y, width, height, 0, 0, 0, height, bits,
  325.             bmi, DIB_RGB_COLORS);
  326.  
  327.         if (oldPal != (HPALETTE)NULL)
  328.         {
  329.             SelectPalette(hdc, oldPal, TRUE);
  330.             RealizePalette(hdc);
  331.         }
  332.  
  333.         GlobalUnlock(hbm);
  334.  
  335.         return TRUE;
  336.     }
  337.  
  338.     return FALSE;
  339. }
  340.  
  341. /*
  342. ** BOOL                    TRUE if successful, FALSE if an error occurred
  343. ** StretchDIBitmap(
  344. **   HDC hdc,            Handle of target device context
  345. **   int x,                X coordinate to draw bitmap at
  346. **   int y,                Y coordinate to draw bitmap at
  347. **      int tWidth,        Width to stretch to
  348. **      int tHeight,        Height to stretch to
  349. **   HDIB hbm);        Handle of memory block holding packed DIB
  350. **
  351. **    This function draws the specified DI bitmap onto the target device
  352. **    context at the given coordinates.  If an error occurs, the FALSE will
  353. **    be returned to the caller, otherwise TRUE will be returned if the DI
  354. **    bitmap was drawn without a problem.
  355. **
  356. ** Modification History:
  357. ** 09/09/91  LCW  Created
  358. */
  359. BOOL
  360. StretchDIBitmap(HDC hdc, int x, int y, int tWidth, int tHeight, HDIB hbm, HPALETTE palette)
  361. {
  362.     int                width, height;
  363.     BITMAPINFO FAR    *bmi;
  364.     LPSTR                bits;
  365.     HPALETTE            oldPal = (HPALETTE)NULL;
  366.  
  367.     bmi = (BITMAPINFO FAR *)GlobalLock(hbm);
  368.     if (bmi != NULL)
  369.     {
  370.         bits = DIBitmapBits(bmi);
  371.  
  372.         if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
  373.         {
  374.             width = ((BITMAPCOREINFO FAR *)bmi)->bmciHeader.bcWidth;
  375.             height = ((BITMAPCOREINFO FAR *)bmi)->bmciHeader.bcHeight;
  376.         }
  377.         else
  378.         {
  379.             width = (WORD)bmi->bmiHeader.biWidth;
  380.             height = (WORD)bmi->bmiHeader.biHeight;
  381.         }
  382.  
  383.         if (palette != (HPALETTE)NULL)
  384.         {
  385.             oldPal = SelectPalette(hdc, palette, FALSE);
  386.             RealizePalette(hdc);
  387.         }
  388.  
  389.         if (tWidth == 0)
  390.         {
  391.             /*
  392.             **    Perform scaling if the target width is 0, using the target height
  393.             **    as the scaling factor * 100.
  394.             */    
  395.             tWidth = (int)(((long)width * (long)tHeight) / 100L);
  396.             tHeight = (int)(((long)height * (long)tHeight) / 100L);
  397.         }
  398.  
  399.         SetStretchBltMode(hdc, COLORONCOLOR);
  400.         StretchDIBits(hdc, x, y, tWidth, tHeight,
  401.             0, 0, width, height, bits, bmi, DIB_RGB_COLORS,
  402.             SRCCOPY);
  403.  
  404.         if (oldPal != (HPALETTE)NULL)
  405.         {
  406.             SelectPalette(hdc, oldPal, TRUE);
  407.             RealizePalette(hdc);
  408.         }
  409.  
  410.         GlobalUnlock(hbm);
  411.  
  412.         return TRUE;
  413.     }
  414.  
  415.     return FALSE;
  416. }
  417.  
  418. /*
  419. ** HBITMAP                            Handle of duplicate if it could be created
  420. ** CopyBitmap(HBITMAP hbm);    Handle of bitmap to copy
  421. **
  422. **    This function will create a duplicate of the passed bitmap, returning
  423. **    the handle of the new bitmap if successful, and NULL if it could not
  424. **    perform the copy.
  425. **
  426. ** Modification History:
  427. ** 09/09/91  LCW  Created
  428. */
  429. HBITMAP
  430. CopyBitmap(HBITMAP hbm)
  431. {
  432.     HBITMAP    hbmNew = (HBITMAP)NULL;
  433.     HBITMAP    oldBm;
  434.     HDC        hdcMem;
  435.     BITMAP    bm;
  436.  
  437.     GetObject(hbm, sizeof(bm), (LPSTR)&bm);
  438.     hdcMem = CreateCompatibleDC(NULL);
  439.     if (hdcMem != (HDC)NULL)
  440.     {
  441.         oldBm = SelectObject(hdcMem, hbm);
  442.         hbmNew = CreateCompatibleBitmap(hdcMem, bm.bmWidth, bm.bmHeight);
  443.         if (hbmNew != (HBITMAP)NULL)
  444.         {
  445.             SelectObject(hdcMem, hbmNew);
  446.             DrawBitmap(hdcMem, 0, 0, hbm);
  447.         }
  448.         SelectObject(hdcMem, oldBm);
  449.         DeleteDC(hdcMem);
  450.     }
  451.  
  452.     return hbmNew;
  453. }
  454.  
  455. /*
  456. ** HDIB                            Handle of newly created DI Bitmap
  457. ** CopyDIBitmap(HDIB hbm);    Handle of DI Bitmap to copy
  458. **
  459. **    This function will create a dupilicate of the passed packed DI Bitmap,
  460. **    returning a handle to the newly created memory block.  If the copy could
  461. **    not be performed, then NULL is returned.
  462. **
  463. ** Modification History:
  464. ** 09/09/91  LCW  Created
  465. */
  466. HDIB
  467. CopyDIBitmap(HDIB hbm)
  468. {
  469.     DWORD    size;
  470.     HDIB    hbmNew;
  471.  
  472.     size = GlobalSize(hbm);
  473.     if (size != 0)
  474.     {
  475.         hbmNew = GlobalAlloc(GMEM_MOVEABLE, size);
  476.         if (hbmNew != (HANDLE)NULL)
  477.         {
  478.             BYTE HUGE *src;
  479.             BYTE HUGE *dest;
  480.  
  481.             src = (BYTE HUGE *)GlobalLock(hbm);
  482.             if (src != NULL)
  483.             {
  484.                 dest = (BYTE HUGE *)GlobalLock(hbmNew);
  485.                 if (dest != NULL)
  486.                 {
  487.                     while (size != 0)
  488.                     {
  489.                         *dest = *src;
  490. #if    defined(__TSC__)
  491.                         if (FP_OFF(dest) == 0xffff)
  492.                         {
  493.                             dest = MK_FP(FP_SEG(dest) + 8, 0);
  494.                         }
  495.                         else
  496.                             ++dest;
  497.  
  498.                         if (FP_OFF(src) == 0xffff)
  499.                         {
  500.                             src = MK_FP(FP_SEG(src) + 8, 0);
  501.                         }
  502.                         else
  503.                             ++src;
  504. #else
  505.                         ++dest;
  506.                         ++src;
  507. #endif
  508.                         --size;
  509.                     }
  510.                     GlobalUnlock(hbmNew);
  511.                 }
  512.                 else
  513.                 {
  514.                     GlobalFree(hbmNew);
  515.                     hbmNew = (HANDLE)NULL;
  516.                 }
  517.                 GlobalUnlock(hbm);
  518.             }
  519.         }
  520.     }
  521.  
  522.     return hbmNew;
  523. }
  524.  
  525. /*
  526. ** HBITMAP                        handle of logical bitmap created, or NULL
  527. ** DibToBitmap(HDIB hbm);    handle of packed DIB to convert
  528. **
  529. **    This function converts a packed DIB into a logical bitmap, returning
  530. **    a handle to the resulting bitmap.
  531. **
  532. ** Modification History:
  533. ** 10/16/91  LCW  Created
  534. */
  535. HBITMAP
  536. DibToBitmap(HDIB hbm)
  537. {
  538.     HBITMAP            bm = (HBITMAP)NULL;
  539.     HDC                hdc;
  540.     BITMAPINFO FAR    *bmi;
  541.     LPSTR                bits;
  542.  
  543.     bmi = (BITMAPINFO FAR *)GlobalLock(hbm);
  544.     if (bmi != NULL)
  545.     {
  546.         hdc = GetDC(MainWindow);
  547.         if (hdc != (HDC)NULL)
  548.         {
  549.             bits = DIBitmapBits(bmi);
  550.  
  551.             bm = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER)bmi, CBM_INIT,
  552.                 bits, bmi, DIB_RGB_COLORS);
  553.  
  554.             ReleaseDC(MainWindow, hdc);
  555.         }
  556.  
  557.         GlobalUnlock(hbm);
  558.     }
  559.  
  560.     return bm;
  561. }
  562.  
  563. /*
  564. ** HDIB                    handle of new packed DIB (NULL if an error occurred)
  565. ** BitmapToDIB(
  566. **   HBITMAP hbm,        handle of logical bitmap to convert
  567. **   int mode);        mode to use when converting
  568. **
  569. **    This function will convert a logical bitmap into a packed Device
  570. **    Independant Bitmap, using the mode parameter to determine if the resulting
  571. **    DIB should be run length encoded (mode == 1), a OS/2 compatible DIB
  572. **    (mode == 2) or a unencoded DIB (mode == 0).
  573. **
  574. ** Modification History:
  575. ** 09/07/91  LCW  Created
  576. */
  577. HDIB
  578. BitmapToDIB(HBITMAP hbm, int mode)
  579. {
  580.     int                i;
  581.     HDC                hdc;
  582.     HDIB                result = (HDIB)NULL;
  583.     BITMAPINFO        *bmi;
  584.     BITMAPCOREINFO    *bmci;
  585.     LPSTR                ptr, sptr, dptr;
  586.     int                hdrSize;
  587.     int                bitsPerPixel;
  588.     BITMAP            bm;
  589.  
  590.     /*
  591.     **    Get bitmap information
  592.     */
  593.     GetObject(hbm, sizeof(bm), (LPSTR)&bm);
  594.     if (bm.bmPlanes == 1)
  595.         bitsPerPixel = bm.bmBitsPixel;
  596.     else
  597.         bitsPerPixel = bm.bmPlanes;
  598.  
  599.  
  600.     if (mode == 2)
  601.     {
  602.         /*
  603.         **    Building a OS/2 bitmap - allocate a LPBITMAPCOREINFO record
  604.         */
  605.         hdrSize = sizeof(BITMAPCOREHEADER);
  606.         switch (bitsPerPixel)
  607.         {
  608.             case 1:
  609.                 hdrSize += 2 * sizeof(RGBTRIPLE);
  610.                 break;
  611.  
  612.             case 3:
  613.                 ++bitsPerPixel;
  614.             case 4:
  615.                 hdrSize += 16 * sizeof(RGBTRIPLE);
  616.                 break;
  617.  
  618.             case 8:
  619.                 hdrSize += 256 * sizeof(RGBTRIPLE);
  620.                 break;
  621.         }
  622.         bmci = (BITMAPCOREINFO *)malloc(hdrSize);
  623.         bmci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
  624.         bmci->bmciHeader.bcWidth = bm.bmWidth;
  625.         bmci->bmciHeader.bcHeight = bm.bmHeight;
  626.         bmci->bmciHeader.bcPlanes = 1;
  627.         bmci->bmciHeader.bcBitCount = bitsPerPixel;
  628.         bmi = NULL;
  629.     }
  630.     else
  631.     {
  632.         /*
  633.         **    Building a Windows compatible Bitmap
  634.         */
  635.         hdrSize = sizeof(BITMAPINFOHEADER);
  636.  
  637.         switch (bitsPerPixel)
  638.         {
  639.             case 1:
  640.                 hdrSize += 2 * sizeof(RGBQUAD);
  641.                 break;
  642.  
  643.             case 3:
  644.                 ++bitsPerPixel;
  645.             case 4:
  646.                 hdrSize += 16 * sizeof(RGBQUAD);
  647.                 break;
  648.  
  649.             case 8:
  650.                 hdrSize += 256 * sizeof(RGBQUAD);
  651.                 break;
  652.         }
  653.         bmi = (BITMAPINFO *)malloc(hdrSize);
  654.  
  655.         bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  656.         bmi->bmiHeader.biWidth = bm.bmWidth;
  657.         bmi->bmiHeader.biHeight = bm.bmHeight;
  658.         bmi->bmiHeader.biPlanes = 1;
  659.         bmi->bmiHeader.biBitCount = bitsPerPixel;
  660.         if (mode == 0 || (bitsPerPixel != 8 && bitsPerPixel != 4))
  661.             bmi->bmiHeader.biCompression = BI_RGB;
  662.         else if (bitsPerPixel == 8)
  663.             bmi->bmiHeader.biCompression = BI_RLE8;
  664.         else
  665.             bmi->bmiHeader.biCompression = BI_RLE4;
  666.         bmi->bmiHeader.biSizeImage = 0;
  667.         bmi->bmiHeader.biXPelsPerMeter = 0;
  668.         bmi->bmiHeader.biYPelsPerMeter = 0;
  669.         bmi->bmiHeader.biClrUsed = 0;
  670.         bmi->bmiHeader.biClrImportant = 0;
  671.         bmci = NULL;
  672.     }
  673.  
  674.     /*
  675.     **    Get a DC to use
  676.     */
  677.     hdc = GetDC(MainWindow);
  678.     if (hdc != (HDC)NULL)
  679.     {
  680.         /*
  681.         **    Allocate storage needed
  682.         */
  683.         if (bmi == NULL)
  684.         {
  685.             DWORD    bitSize = (DWORD)bm.bmWidth * (DWORD)bitsPerPixel / 8;
  686.             if ((bitSize & 3) != 0)
  687.                 bitSize += 4 - (bitSize & 3);
  688.                 
  689.             result = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
  690.                 (long)hdrSize + (DWORD)bm.bmHeight * bitSize);
  691.  
  692.             if (result != (HANDLE)NULL)
  693.             {
  694.                 ptr = (LPSTR)GlobalLock(result);
  695.                 if (ptr == NULL)
  696.                 {
  697.                     GlobalFree(result);
  698.                     result = (HANDLE)NULL;
  699.                     ErrorBox("BitmapToDIB(): Unable to lock DIB memory");
  700.                 }
  701.                 else
  702.                 {
  703.                     sptr = (LPSTR)bmci;
  704.                 }
  705.             }
  706.         }
  707.         else
  708.         {
  709.             if (GetDIBits(hdc, hbm, 0, bm.bmHeight, NULL, (LPBITMAPINFO)bmi, DIB_RGB_COLORS))
  710.             {
  711.                 result = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
  712.                     (long)hdrSize + bmi->bmiHeader.biSizeImage);
  713.  
  714.                 if (result != (HANDLE)NULL)
  715.                 {
  716.                     ptr = (LPSTR)GlobalLock(result);
  717.                     if (ptr == NULL)
  718.                     {
  719.                         GlobalFree(result);
  720.                         result = (HANDLE)NULL;
  721.                         ErrorBox("BitmapToDIB(): Unable to lock DIB memory");
  722.                     }
  723.                     else
  724.                     {
  725.                         sptr = (LPSTR)bmi;
  726.                     }
  727.                 }
  728.             }
  729.         }
  730.  
  731.         if (result)
  732.         {
  733.             /*
  734.             **    Copy header
  735.             */
  736.             dptr = ptr;
  737.             for (i = 0 ; i < hdrSize ; ++i)
  738.             {
  739.                 *dptr++ = *sptr++;
  740.             }
  741.  
  742.             /*
  743.             **    Get the bits
  744.             */
  745.             if (!GetDIBits(hdc, hbm, 0, bm.bmHeight, dptr, (LPBITMAPINFO)ptr, DIB_RGB_COLORS))
  746.             {
  747.                 GlobalUnlock(result);
  748.                 GlobalFree(result);
  749.                 result = (HANDLE)NULL;
  750.             }
  751.             else
  752.             {
  753.                 GlobalUnlock(result);
  754.             }
  755.         }
  756.         ReleaseDC(MainWindow, hdc);
  757.     }
  758.     else
  759.     {
  760.         ErrorBox("BitmapToDIB(): Unable to get DC from main window");
  761.     }
  762.  
  763.     if (bmi != NULL)
  764.         free(bmi);
  765.  
  766.     if (bmci != NULL)
  767.         free(bmci);
  768.  
  769.     return result;
  770. }
  771.  
  772. /*
  773. ** int                        TRUE if hbm points to a OS/2 DIB
  774. ** DibIsOs2(HDIB hbm);    handle of packed DIB to check
  775. **
  776. **    This function checks the passd packed DIB to determine if it is a
  777. **    OS/2 compatible DIB.
  778. **
  779. ** Modification History:
  780. ** 10/16/91  LCW  Created
  781. */
  782. int
  783. DibIsOs2(HDIB hbm)
  784. {
  785.     int                rc = FALSE;
  786.     BITMAPINFO FAR    *bmi;
  787.  
  788.     bmi = (BITMAPINFO FAR *)GlobalLock(hbm);
  789.     if (bmi != NULL)
  790.     {
  791.         if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
  792.             rc = TRUE;
  793.  
  794.         GlobalUnlock(hbm);
  795.     }
  796.  
  797.     return rc;
  798. }
  799.  
  800. /*
  801. ** int                                TRUE if hbm points to a compressed DIB
  802. ** DibIsCompressed(HDIB hbm);    handle of packed DIB to check
  803. **
  804. **    This function checks the passed packed DIB to determine if it is
  805. **    a compressed windows DIB or not.
  806. **
  807. ** Modification History:
  808. ** 10/16/91  LCW  Created
  809. */
  810. int
  811. DibIsCompressed(HDIB hbm)
  812. {
  813.     int                rc = FALSE;
  814.     BITMAPINFO FAR    *bmi;
  815.  
  816.     bmi = (BITMAPINFO FAR *)GlobalLock(hbm);
  817.     if (bmi != NULL)
  818.     {
  819.         if (bmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)
  820.             && bmi->bmiHeader.biCompression != BI_RGB)
  821.             rc = TRUE;
  822.  
  823.         GlobalUnlock(hbm);
  824.     }
  825.  
  826.     return rc;
  827. }
  828.  
  829. /*
  830. **    Modification History
  831. **    --------------------
  832. **    $lgb$
  833. ** 10/15/91     Larry Widing   Initial version for Win Tech Journal Article.
  834. ** 11/12/91     Larry Widing   Added DibIsOs2() and DibIsCompressed()
  835. **                             fucntions.
  836. ** 02/10/92     Larry Widing   
  837. ** 08/03/92     Larry Widing   Added StretchDIBitmap().
  838. **    $lge$
  839. */
  840.